//+------------------------------------------------------------------+
//| 五浪理论遗传算法优化器
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_NONE

// 输入参数
input int    GAPopulationSize = 30;       // 种群大小
input int    GAGenerations = 50;          // 代数
input double GAMutationRate = 0.15;       // 变异率
input double GACrossoverRate = 0.8;       // 交叉率
input int    GAMinTrades = 10;            // 最小交易次数
input double GAMinWinRate = 0.4;          // 最小胜率
input double GAMinProfitFactor = 1.2;     // 最小盈亏比
input int    GAMaxDrawdown = 20;          // 最大回撤(%)

// 指标缓冲区
double OptimizationBuffer[];

// 个体结构
struct WaveTheoryIndividual {
    // 波浪识别参数
    double wave1MinAmplitude;      // 第1浪最小幅度
    double wave2RetracementMin;    // 第2浪最小回撤
    double wave2RetracementMax;    // 第2浪最大回撤
    double wave3ExtensionMin;      // 第3浪最小延伸
    double wave3ExtensionMax;      // 第3浪最大延伸
    double wave4RetracementMin;    // 第4浪最小回撤
    double wave4RetracementMax;    // 第4浪最大回撤
    double wave5ExtensionMin;      // 第5浪最小延伸
    
    // 适应度指标
    double fitness;                // 综合适应度
    double winRate;                // 胜率
    double profitFactor;           // 盈亏比
    double maxDrawdown;            // 最大回撤
    double sharpeRatio;            // 夏普比率
};

// 全局变量
WaveTheoryIndividual g_population[];      // 种群
WaveTheoryIndividual g_bestIndividual;    // 最佳个体
int g_currentGeneration = 0;              // 当前代数
datetime g_lastOptimizationTime = 0;      // 上次优化时间

//+------------------------------------------------------------------+
//| Custom indicator initialization function
//+------------------------------------------------------------------+
int OnInit() {
    // 设置指标缓冲区
    SetIndexBuffer(0, OptimizationBuffer, INDICATOR_DATA);
    
    // 设置指标名称
    IndicatorSetString(INDICATOR_SHORTNAME, "Wave Theory GA Optimizer");
    
    // 初始化种群
    InitializePopulation();
    
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]) {
    
    // 检查是否需要优化
    if(!ShouldOptimize()) return(rates_total);
    
    // 执行优化
    Optimize();
    
    // 更新缓冲区
    UpdateBuffer();
    
    return(rates_total);
}

//+------------------------------------------------------------------+
//| 初始化种群
//+------------------------------------------------------------------+
void InitializePopulation() {
    ArrayResize(g_population, GAPopulationSize);
    
    for(int i = 0; i < GAPopulationSize; i++) {
        // 初始化波浪参数
        g_population[i].wave1MinAmplitude = 0.0001 + (MathRand() % 100) / 100000.0;
        g_population[i].wave2RetracementMin = 0.236 + (MathRand() % 20) / 1000.0;
        g_population[i].wave2RetracementMax = 0.618 + (MathRand() % 20) / 1000.0;
        g_population[i].wave3ExtensionMin = 1.0 + (MathRand() % 50) / 100.0;
        g_population[i].wave3ExtensionMax = 1.618 + (MathRand() % 50) / 100.0;
        g_population[i].wave4RetracementMin = 0.236 + (MathRand() % 20) / 1000.0;
        g_population[i].wave4RetracementMax = 0.618 + (MathRand() % 20) / 1000.0;
        g_population[i].wave5ExtensionMin = 1.0 + (MathRand() % 30) / 100.0;
        
        // 初始化适应度指标
        g_population[i].fitness = 0;
        g_population[i].winRate = 0;
        g_population[i].profitFactor = 0;
        g_population[i].maxDrawdown = 0;
        g_population[i].sharpeRatio = 0;
    }
    
    // 初始化最佳个体
    g_bestIndividual = g_population[0];
}

//+------------------------------------------------------------------+
//| 检查是否需要优化
//+------------------------------------------------------------------+
bool ShouldOptimize() {
    // 检查是否达到最大代数
    if(g_currentGeneration >= GAGenerations) return false;
    
    // 检查时间间隔
    datetime currentTime = TimeCurrent();
    if(currentTime - g_lastOptimizationTime < 3600) return false;  // 每小时优化一次
    
    g_lastOptimizationTime = currentTime;
    return true;
}

//+------------------------------------------------------------------+
//| 执行优化
//+------------------------------------------------------------------+
void Optimize() {
    // 评估种群
    EvaluatePopulation();
    
    // 选择操作
    Selection();
    
    // 交叉操作
    Crossover();
    
    // 变异操作
    Mutation();
    
    // 更新代数
    g_currentGeneration++;
}

//+------------------------------------------------------------------+
//| 评估种群
//+------------------------------------------------------------------+
void EvaluatePopulation() {
    for(int i = 0; i < GAPopulationSize; i++) {
        // 评估个体
        EvaluateIndividual(g_population[i]);
        
        // 更新最佳个体
        if(g_population[i].fitness > g_bestIndividual.fitness) {
            g_bestIndividual = g_population[i];
        }
    }
}

//+------------------------------------------------------------------+
//| 评估个体
//+------------------------------------------------------------------+
void EvaluateIndividual(WaveTheoryIndividual &individual) {
    // 模拟交易
    SimulateTrades(individual);
    
    // 计算适应度
    individual.fitness = CalculateFitness(individual);
}

//+------------------------------------------------------------------+
//| 模拟交易
//+------------------------------------------------------------------+
void SimulateTrades(WaveTheoryIndividual &individual) {
    // 获取历史数据
    double high[], low[], close[];
    ArraySetAsSeries(high, true);
    ArraySetAsSeries(low, true);
    ArraySetAsSeries(close, true);
    
    int copied = CopyHigh(_Symbol, PERIOD_CURRENT, 0, 1000, high);
    if(copied != 1000) return;
    
    copied = CopyLow(_Symbol, PERIOD_CURRENT, 0, 1000, low);
    if(copied != 1000) return;
    
    copied = CopyClose(_Symbol, PERIOD_CURRENT, 0, 1000, close);
    if(copied != 1000) return;
    
    // 模拟交易
    int wins = 0;
    int losses = 0;
    double totalProfit = 0;
    double totalLoss = 0;
    double maxDrawdown = 0;
    double peak = 0;
    double equity = 1000;
    
    for(int i = 100; i < 1000; i++) {
        // 检查是否形成完整的五浪结构
        if(IsCompleteWaveStructure(i, high, low, close, individual)) {
            // 生成交易信号
            double signal = GenerateSignal(i, high, low, close, individual);
            
            if(signal != 0) {
                // 计算交易结果
                double profit = CalculateTradeProfit(i, signal, high, low, close);
                
                if(profit > 0) {
                    wins++;
                    totalProfit += profit;
                } else {
                    losses++;
                    totalLoss += MathAbs(profit);
                }
                
                // 更新权益
                equity += profit;
                
                // 更新最大回撤
                if(equity > peak) {
                    peak = equity;
                }
                double drawdown = (peak - equity) / peak;
                if(drawdown > maxDrawdown) {
                    maxDrawdown = drawdown;
                }
            }
        }
    }
    
    // 更新个体指标
    individual.winRate = (double)wins / (wins + losses);
    individual.profitFactor = (totalLoss > 0) ? (totalProfit / totalLoss) : 0;
    individual.maxDrawdown = maxDrawdown;
    individual.sharpeRatio = CalculateSharpeRatio(equity, 1000, wins + losses);
}

//+------------------------------------------------------------------+
//| 计算适应度
//+------------------------------------------------------------------+
double CalculateFitness(const WaveTheoryIndividual &individual) {
    // 检查最小要求
    if(individual.winRate < GAMinWinRate) return 0;
    if(individual.profitFactor < GAMinProfitFactor) return 0;
    if(individual.maxDrawdown > GAMaxDrawdown / 100.0) return 0;
    
    // 计算综合适应度
    double fitness = individual.winRate * 0.3 +                    // 胜率权重30%
                    individual.profitFactor * 0.3 +                // 盈亏比权重30%
                    (1.0 - individual.maxDrawdown) * 0.2 +         // 回撤权重20%
                    individual.sharpeRatio * 0.2;                  // 夏普比率权重20%
    
    return fitness;
}

//+------------------------------------------------------------------+
//| 选择操作
//+------------------------------------------------------------------+
void Selection() {
    // 创建新种群
    WaveTheoryIndividual newPopulation[];
    ArrayResize(newPopulation, GAPopulationSize);
    
    // 计算总适应度
    double totalFitness = 0;
    for(int i = 0; i < GAPopulationSize; i++) {
        totalFitness += g_population[i].fitness;
    }
    
    // 轮盘赌选择
    for(int i = 0; i < GAPopulationSize; i++) {
        double random = MathRand() / 32768.0 * totalFitness;
        double cumulative = 0;
        
        for(int j = 0; j < GAPopulationSize; j++) {
            cumulative += g_population[j].fitness;
            if(cumulative >= random) {
                newPopulation[i] = g_population[j];
                break;
            }
        }
    }
    
    // 更新种群
    ArrayCopy(g_population, newPopulation);
}

//+------------------------------------------------------------------+
//| 交叉操作
//+------------------------------------------------------------------+
void Crossover() {
    for(int i = 0; i < GAPopulationSize - 1; i += 2) {
        if(MathRand() / 32768.0 < GACrossoverRate) {
            // 波浪参数交叉
            if(MathRand() % 2 == 0) {
                double temp = g_population[i].wave2RetracementMin;
                g_population[i].wave2RetracementMin = g_population[i+1].wave2RetracementMin;
                g_population[i+1].wave2RetracementMin = temp;
            }
            
            if(MathRand() % 2 == 0) {
                double temp = g_population[i].wave3ExtensionMin;
                g_population[i].wave3ExtensionMin = g_population[i+1].wave3ExtensionMin;
                g_population[i+1].wave3ExtensionMin = temp;
            }
            
            if(MathRand() % 2 == 0) {
                double temp = g_population[i].wave4RetracementMin;
                g_population[i].wave4RetracementMin = g_population[i+1].wave4RetracementMin;
                g_population[i+1].wave4RetracementMin = temp;
            }
        }
    }
}

//+------------------------------------------------------------------+
//| 变异操作
//+------------------------------------------------------------------+
void Mutation() {
    for(int i = 0; i < GAPopulationSize; i++) {
        if(MathRand() / 32768.0 < GAMutationRate) {
            // 随机选择参数进行变异
            int param = MathRand() % 8;
            
            switch(param) {
                case 0:
                    g_population[i].wave1MinAmplitude += (MathRand() % 20 - 10) / 100000.0;
                    break;
                case 1:
                    g_population[i].wave2RetracementMin += (MathRand() % 20 - 10) / 1000.0;
                    break;
                case 2:
                    g_population[i].wave2RetracementMax += (MathRand() % 20 - 10) / 1000.0;
                    break;
                case 3:
                    g_population[i].wave3ExtensionMin += (MathRand() % 20 - 10) / 100.0;
                    break;
                case 4:
                    g_population[i].wave3ExtensionMax += (MathRand() % 20 - 10) / 100.0;
                    break;
                case 5:
                    g_population[i].wave4RetracementMin += (MathRand() % 20 - 10) / 1000.0;
                    break;
                case 6:
                    g_population[i].wave4RetracementMax += (MathRand() % 20 - 10) / 1000.0;
                    break;
                case 7:
                    g_population[i].wave5ExtensionMin += (MathRand() % 20 - 10) / 100.0;
                    break;
            }
            
            // 确保参数在合理范围内
            ValidateIndividual(g_population[i]);
        }
    }
}

//+------------------------------------------------------------------+
//| 验证个体参数
//+------------------------------------------------------------------+
void ValidateIndividual(WaveTheoryIndividual &individual) {
    // 确保最小幅度大于0
    individual.wave1MinAmplitude = MathMax(individual.wave1MinAmplitude, 0.0001);
    
    // 确保回撤比例在0-1之间
    individual.wave2RetracementMin = MathMax(0, MathMin(1, individual.wave2RetracementMin));
    individual.wave2RetracementMax = MathMax(0, MathMin(1, individual.wave2RetracementMax));
    individual.wave4RetracementMin = MathMax(0, MathMin(1, individual.wave4RetracementMin));
    individual.wave4RetracementMax = MathMax(0, MathMin(1, individual.wave4RetracementMax));
    
    // 确保延伸比例大于1
    individual.wave3ExtensionMin = MathMax(1, individual.wave3ExtensionMin);
    individual.wave3ExtensionMax = MathMax(1, individual.wave3ExtensionMax);
    individual.wave5ExtensionMin = MathMax(1, individual.wave5ExtensionMin);
    
    // 确保最小回撤小于最大回撤
    if(individual.wave2RetracementMin > individual.wave2RetracementMax) {
        double temp = individual.wave2RetracementMin;
        individual.wave2RetracementMin = individual.wave2RetracementMax;
        individual.wave2RetracementMax = temp;
    }
    
    if(individual.wave4RetracementMin > individual.wave4RetracementMax) {
        double temp = individual.wave4RetracementMin;
        individual.wave4RetracementMin = individual.wave4RetracementMax;
        individual.wave4RetracementMax = temp;
    }
}

//+------------------------------------------------------------------+
//| 更新缓冲区
//+------------------------------------------------------------------+
void UpdateBuffer() {
    // 将最佳个体的适应度写入缓冲区
    for(int i = 0; i < GAPopulationSize; i++) {
        OptimizationBuffer[i] = g_population[i].fitness;
    }
}

//+------------------------------------------------------------------+
//| 计算夏普比率
//+------------------------------------------------------------------+
double CalculateSharpeRatio(double finalEquity, double initialEquity, int trades) {
    if(trades == 0) return 0;
    
    double returns = (finalEquity - initialEquity) / initialEquity;
    double avgReturn = returns / trades;
    
    // 简化计算，假设风险为1
    return avgReturn;
} 